home *** CD-ROM | disk | FTP | other *** search
/ Chip 2001 June / CHIP Haziran 2001.iso / prog / haziran / 19 / setup.exe / data.z / p9050_serial.c < prev    next >
C/C++ Source or Header  |  2001-04-11  |  6KB  |  169 lines

  1. ////////////////////////////////////////////////////////////////
  2. // File - P9050_SERIAL.C
  3. //
  4. // This is a serial port driver for PLX 9050 RDK board.
  5. //
  6. // To use this driver, install the PLX 9050 RDK board, plug in
  7. // to the piggyback ISA connector the serial port or modem ISA
  8. // card. Run this driver.
  9. // Your ISA serial port will be detected, and written into the
  10. // registry. After rebooting, a new COM port will be added, that
  11. // will allow you to access your legacy ISA card.
  12. // 
  13. ////////////////////////////////////////////////////////////////
  14.  
  15. #include <windows.h>
  16. #include <winioctl.h>
  17. #include "../../../include/windrvr.h"
  18. #include "../lib/p9050_lib.c"
  19. #include <stdio.h>
  20.  
  21. CHAR *sApp = "PLX 9050 Serial Driver";
  22.  
  23. DWORD PLX_DetectInterrupt(P9050_HANDLE hPlx, DWORD dwVendorID, DWORD dwDeviceID, DWORD nCardNum)
  24. {
  25.     WD_PCI_SCAN_CARDS pciScan;
  26.     WD_PCI_CARD_INFO pciCardInfo;
  27.     DWORD i;
  28.  
  29.     BZERO(pciScan);
  30.     pciScan.searchId.dwVendorId = dwVendorID;
  31.     pciScan.searchId.dwDeviceId = dwDeviceID;
  32.     WD_PciScanCards (hPlx->hWD, &pciScan);
  33.     if (pciScan.dwCards<=nCardNum)
  34.         return 0; // no cards found
  35.  
  36.     BZERO(pciCardInfo);
  37.     pciCardInfo.pciSlot = pciScan.cardSlot[nCardNum];
  38.     WD_PciGetCardInfo (hPlx->hWD, &pciCardInfo);
  39.  
  40.     // search for interrupt item
  41.     for (i=0; i<pciCardInfo.Card.dwItems; i++)
  42.     {
  43.         if (pciCardInfo.Card.Item[i].item==ITEM_INTERRUPT)
  44.             return pciCardInfo.Card.Item[i].I.Int.dwInterrupt;
  45.     }
  46.  
  47.     return 0; // interrupt not found
  48. }
  49.  
  50. // The main window loop.
  51. // WinMain() opens a handle for speaker, and then creates the main menu window.
  52. int PASCAL WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpszCmdLine, int nCmdShow )
  53. {
  54.     // IO addresses of serial ports on the local bus attached to the PLX 9050 board
  55.     DWORD dwSerialAddr[] = {0x3f8, 0x2f8, 0x3e8, 0x2e8, 0xffffffff};
  56.     // start creating com ports from COM5
  57.     DWORD dwComPort = 5; 
  58.  
  59.     P9050_HANDLE hPlx = NULL;
  60.     DWORD dwVendorID = 0x10b5;
  61.     DWORD dwDeviceID = 0x9050;
  62.     DWORD nCardNum = 0; // use this if you have more than one plx 9050 boards installed.
  63.     DWORD dwInterrupt;
  64.  
  65.     DWORD res;
  66.     DWORD val;
  67.     CHAR sTmp[256];
  68.     DWORD i;
  69.     OSVERSIONINFO lVerInfo;
  70.     HKEY hKey;
  71.  
  72.     DWORD dwFound = 0;
  73.     int retVal = FALSE;
  74.     
  75.     lVerInfo.dwOSVersionInfoSize = sizeof (lVerInfo);
  76.     GetVersionEx (&lVerInfo);
  77.     switch (lVerInfo.dwPlatformId)
  78.     {
  79.         case VER_PLATFORM_WIN32_NT:
  80.             break;
  81.  
  82.         case VER_PLATFORM_WIN32_WINDOWS:
  83.         default:
  84.             MessageBox( NULL, "This driver will only work on Windows NT\n", sApp, MB_OK | MB_ICONERROR );
  85.             goto Exit;
  86.     }    
  87.     
  88.     // open PLX 9050 card WITHOUT interrupts.
  89.     // sometimes there might be problems with interrupt sharing
  90.     if (!P9050_Open( &hPlx, dwVendorID, dwDeviceID, nCardNum, 0))
  91.     {
  92.         MessageBox( NULL, P9050_ErrorString, sApp, MB_OK | MB_ICONERROR );
  93.         goto Exit;
  94.     }
  95.  
  96.     // since we opened the card without interrupts, then we have to fetch
  97.     // the interrupt information ourselves
  98.     dwInterrupt = PLX_DetectInterrupt(hPlx, dwVendorID, dwDeviceID, nCardNum);
  99.     if (!dwInterrupt)
  100.     {
  101.         MessageBox( NULL, "No interrupt allocated for card\n", sApp, MB_OK | MB_ICONERROR );
  102.         goto Exit;
  103.     }
  104.  
  105.     // the standard serial port can only access IO mapped devices
  106.     if (hPlx->addrDesc[P9050_ADDR_SPACE1].fIsMemory)
  107.     {
  108.         MessageBox( NULL, "Address space 1 (BAR3) must be IO mapped in order that the standard serial driver can access it\n", 
  109.             sApp, MB_OK | MB_ICONERROR );
  110.         goto Exit;
  111.     }
  112.  
  113.     // Sanity check: is address space 1 mapped 0x0-0x3ff IO range.
  114.     // If your plx device is configured differently, then you can adjust this test
  115.     // to the size you programmed address space 1.
  116.     if (hPlx->addrDesc[P9050_ADDR_SPACE1].dwBytes != 0x400)
  117.     {
  118.         MessageBox( NULL, "Expected address space 1 (BAR3) to be of size 0x400\n", sApp, MB_OK | MB_ICONERROR );
  119.         goto Exit;
  120.     }
  121.  
  122.     // test the PLX 9050 local bus for serial ports
  123.     for (i=0; dwSerialAddr[i]!=0xffffffff; i++)
  124.     {
  125.         DWORD dwAddr = dwSerialAddr[i];
  126.         DWORD dwVal0, dwVal1, dwVal2;
  127.  
  128.         // Validation: is there a serial port at this address?
  129.         dwVal0 = P9050_ReadSpaceByte( hPlx, P9050_ADDR_SPACE1, dwAddr);
  130.         dwVal1 = P9050_ReadSpaceByte( hPlx, P9050_ADDR_SPACE1, dwAddr+1);
  131.         dwVal2 = P9050_ReadSpaceByte( hPlx, P9050_ADDR_SPACE1, dwAddr+2);
  132.         if (dwVal0 == dwVal1 && dwVal1==dwVal2)
  133.         {
  134.             //printf ("all registers have the same values - this is probably not a serial port\n");
  135.             continue;
  136.         }
  137.  
  138.         sprintf (sTmp,"System\\CurrentControlSet\\Services\\Serial\\Parameters\\Serial%d", dwComPort+dwFound-1);
  139.         RegCreateKeyEx (HKEY_LOCAL_MACHINE, sTmp, 0,"",0,KEY_ALL_ACCESS, NULL, &hKey, &res);
  140.         sprintf (sTmp, "COM%d", dwComPort+dwFound);
  141.         RegSetValueEx (hKey, "DosDevices", 0, REG_SZ, sTmp, strlen(sTmp)+1);
  142.         val = 1;
  143.         RegSetValueEx (hKey, "ForceFifoEnable", 0, REG_DWORD, (PVOID) &val, 4);
  144.         val = dwInterrupt;
  145.         RegSetValueEx (hKey, "Interrupt", 0, REG_DWORD, (PVOID) &val, 4);
  146.         val = hPlx->addrDesc[P9050_ADDR_SPACE1].dwAddr + dwAddr;
  147.         RegSetValueEx (hKey, "PortAddress", 0, REG_DWORD, (PVOID) &val, 4);
  148.         RegCloseKey (hKey);
  149.         dwFound ++;
  150.     }
  151.     
  152.     if (dwFound) 
  153.     {
  154.         retVal = TRUE;
  155.         sprintf (sTmp, "%d serial ports were found on the PLX 9050 board.\n"
  156.             "You will need to reboot in order for the serial driver to be activated.", 
  157.             dwFound);
  158.         MessageBox( NULL, sTmp, sApp, MB_OK);
  159.     }
  160.     else
  161.         MessageBox( NULL, "No serial ports found on the PLX 9050 board\n", sApp, MB_OK | MB_ICONERROR );
  162.  
  163. Exit:
  164.     if (hPlx) 
  165.         P9050_Close( hPlx);
  166.     return retVal;
  167. }
  168.  
  169.